/*******************************************************************************
 * Level Master 2000
 * Copyright (C) 2010 Christian Herzog
 * For more information see http://code.google.com/p/levelmaster2000/
 *
 * This file is licensed under the terms of the MIT license, see
 * http://www.opensource.org/licenses/mit-license.php for further information.
 ******************************************************************************/

#ifndef ENTITY_EXPLORER_H
#define ENTITY_EXPLORER_H

#include "ClassInfo.h"
#include "Entity.h"

//#include "commands/DeleteEntityCommand.h"

#include "widgets/ComponentTreeWidgetItem.h"
#include "widgets/EntityTreeWidgetItem.h"
#include "widgets/GroupTreeWidgetItem.h"

#include <QCompleter>
#include <QDockWidget>
#include <QLineEdit>
#include <QTreeView>
#include <QTreeWidget>
#include <QTableWidget>
#include <QLabel>

class QPushButton;
class QUndoStack;

class EntityExplorer : public QDockWidget
{
    Q_OBJECT

    friend class CreateComponentCommand;
    friend class CreateObjectCommand;
    friend class CreateGroupCommand;
    friend class DeleteComponentCommand;
    friend class DeleteEntityCommand;
    friend class DeleteGroupCommand;

public:
    EntityExplorer( QWidget *parent, QUndoStack *undoStack );

    void initComponentCompleter( const QList<ClassInfo> &componentInfo );

    QList<Entity*> selectedEntities();

    template<class TreeWidgetItem>
    TreeWidgetItem findTreeItemByName( QString name )
    {
        QList<QTreeWidgetItem*> items = tree->findItems( name, Qt::MatchRecursive, 0 );

        if( items.count() == 1 )
        {
            return dynamic_cast<TreeWidgetItem>( items[0] );
        }

        return 0;
    }


private:
   // void createComponent( QString entityName, QString componentName, QString componentClassName );
    void createEntity( QString entity, QString group );
    void createGroup( QString group, QString parentGroup );

    void deleteComponent( QString entityName, QString componentName );
    void deleteEntity( QString name );
    void deleteGroup( QString name );

    //void deleteComponent( QString entityName, QString componentName );

public:
    void getEntityXml( QString name );
    void setEntityXml( QString name, QString xml );

    void getComponentXml( QString entityName, QString componentName );
    void setComponentXml( QString entityName, QString componentName, QString xml );

signals:
    void requestGetEntityXml( QString name );
    void requestSetEntityXml( QString name, QString xml );

    void requestGetComponentXml( QString entityName, QString componentName );
    void requestSetComponentXml( QString entityName, QString componentName, QString xml );

    void requestCreateComponent( QString entityName, QString componentName, QString componentClassName );
    void requestCreateEntity( QString entity, QString group );
    void requestCreateGroup( QString group, QString parentGroup );
    void selectEntities( QList<Entity*> entities );
    void deleteObjects( QStringList objects );
    void sigDeleteComponent( QString entityName, QString componentName );
    void showComponentBrowser( bool show );

private slots:

    //Entity or component in entity explorer clicked:
    void clicked( QTreeWidgetItem *item, int column );

    //Executes when return is pressed in the quick add component line edit:
    void createComponentFromLineEdit();

    //New entity button in entity explorer clicked:
    void newEntityButtonClicked();

    //New group button clicked:
    void newGroupButtonClicked();

    //Delete button in entity explorer clicked:
    void deleteObjectButtonClicked();

    //Component browser button in entity explorer clicked:
    void showComponentBrowser();

    //Entity or component in entity explorer double clicked:
    void doubleClicked( QTreeWidgetItem *item, int column );

    void itemSelectionChanged();

    void deleteComponentClicked();

public slots:
    void createComponent( QString componentName, QString className );

    void onNewComponent( QString entityName, QString componentName, QString componentClass );
    void onNewEntity( QString name, QString group );
    void onNewGroup( QString name, QString parent );
    void onDeleteObjects( QStringList objects );
    void onDeleteComponent( QString entityName, QString componentName );

    void onGetComponentXml( QString entityName, QString componentName, QString className, QString xml );
    void onGetEntityXml( QString name, QString xml );
    void onSetEntityXml( QString name, QString xml ); //TODO: needed?

    //void deselectAll();
    void onSelectEntities( QList<Entity*> newEntities );
    void onRequestSelectEntity( QString entityName );

public:
    QTreeWidget*    tree;


    Entity *findEntity( QString name );
    void addEntityToSelection( Entity* entity );
    void addEntitiesToSelection( QList<Entity*> entities );

    void removeEntityFromSelection( Entity* entity );
    void updateLastSelection();

private:
    QPushButton     *newEntityButton;
    QPushButton     *newGroupButton;

    QCompleter*     componentCompleter;
    QTreeView*      componentCompleterTreeView;
    QLineEdit*      componentLineEdit;

    QTableWidget*   componentList;
    QLabel*         componentListLabel;

    QLineEdit*      PBObjectNameLineEdit;

    QList<Entity*>  lastSelection;
    QUndoStack      *undoStack;

    QString entityXml;
    QString componentXml;

private:
    void init();

    void listComponents( Entity *entity );

    Entity* findEntity(QTreeWidgetItem *item);

    void addEntities( GroupTreeWidgetItem *groupItem, QList<Entity*> &entities );

    void enableCreation( bool enable );

    static int entityCounter;

    QDialog* createEntityDialog;
};

#endif
